/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mcet.outliers.data;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.mcet.outliers.log.Log;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 *
 */
public class MedicalMap {
    
    private List<Keyword> medDic;
    private static MedicalMap medMap;
    private MedicalMap() {
        initMedMap();
    }
    
    public synchronized  static MedicalMap getInstance(){
        
        if(medMap==null) {
            medMap = new MedicalMap();
        }
        
        return medMap;
    }
    
    private void initMedMap() {
        
        BufferedReader reader;
        try {
            //reader = new BufferedReader(new FileReader(".\\res\\medMap.json"));
            reader = new BufferedReader(new FileReader(".\\res\\disMap.txt"));
            
            String line = null;
            String json = "";
            while ((line = reader.readLine()) != null) {
               json+=line;
            }
            Gson gson = new  Gson();
            medDic = gson.fromJson(json,new TypeToken<List<Keyword>>(){}.getType());
            for(int i=0;i<medDic.size();i++){
                Log.debug("Key : "+medDic.get(i).getKey()+ " Value : "+medDic.get(i).getValue());
            }
       
        } catch (FileNotFoundException ex) {
            Logger.getLogger(MedicalMap.class.getName()).log(Level.SEVERE, null, ex);
        } catch(IOException ex) {
            Logger.getLogger(MedicalMap.class.getName()).log(Level.SEVERE, null, ex);
        }

        
        
        
      
    }
    
    public float getWeight(String data) {
        for(int i=0;i<this.medDic.size();i++) {
            Keyword keyWord = medDic.get(i);
            
            if(data.toLowerCase().contains(keyWord.getKey().toLowerCase())) {
                //Log.debug("Returning value ::"+keyWord.getValue());
                return keyWord.getValue();
            }
        }
        return 0;
    }
    
    public String getKey(String data) {
        for(int i=0;i<this.medDic.size();i++) {
            Keyword keyWord = medDic.get(i);
            
            if(data.toLowerCase().contains(keyWord.getKey().toLowerCase())) {
                //Log.debug("Returning value ::"+keyWord.getValue());
                return keyWord.getKey();
            }
        }
        return "No Key";
    }
    
    public ArrayList<String>findPossibleValue(ArrayList<String> outlierDatas) {
       
        ArrayList<String> possibleValues = new ArrayList<String>();
        
         float weight[] = new float[outlierDatas.size()];
                
                int outlierColumn = 0;
                    for (String outlierCol : outlierDatas) {
                      
                            String dataStr = outlierDatas.get(outlierColumn);
                            weight[outlierColumn] = this.getWeight(dataStr);
                            outlierColumn++;


                        
                    }

                



                float token = getToken(weight);
                float treshold = token / 2;
                //Log.debug("Token = "+token);
                //Log.debug("treshold = "+treshold);
                boolean outlier = false;
                for (int i = 0; i < weight.length; i++) {
                    weight[i] = weight[i] - token;
                    if (treshold != 0 && weight[i] >= treshold && weight[i] != 0) {
                        outlier = true;
                       
                    }else {
                        possibleValues.add(getKey(outlierDatas.get(i)));
                    }
                }
        
        return possibleValues;
    }
    
     private float getToken(float weight[]) {
        int count[] = new int[weight.length];
        for (int i = 0; i < weight.length; i++) {
            count[i] = 1;
            for (int j = i + 1; j < weight.length; j++) {
                if (weight[i] == weight[j]) {
                    count[i]++;
                }
            }
        }

        /*  System.out.print("Count :");
        for(int i=0;i<count.length;i++) {
        System.out.print(" "+count[i]);
        }
        System.out.println("");*/
        int max = findMax(count);
        // Log.info("Max = "+max);
        int index = findIndex(count, max);
        float token = weight[index];

        return token;
    }
     
      private int findMax(int count[]) {

        int large = count[0];

        for (int i = 1; i < count.length; i++) {
            if (count[i] > large) {
                large = count[i];
            }
        }
        return large;
    }

    private int findIndex(int count[], int num) {

        int index = 0;

        for (index = 0; index < count.length; index++) {
            if (count[index] == num) {
                return index;
            }
        }


        return index;

    }
}
